package com.tyj.movie.controller;


import com.alipay.api.AlipayApiException;
import com.tyj.movie.constant.RedisConstant;
import com.tyj.movie.entity.MovieTheatreShow;
import com.tyj.movie.mapper.MovieTypeMapper;
import com.tyj.movie.service.MovieService;
import com.tyj.movie.service.MovieTheatreOrderService;
import com.tyj.movie.service.MovieTheatreService;
import com.tyj.movie.service.MovieTheatreShowService;
import com.tyj.movie.to.MovieTheatreOrderTo;
import com.tyj.movie.util.AlipayTemplate;
import com.tyj.movie.util.DateUtil;
import com.tyj.movie.util.SecurityUtil;
import com.tyj.movie.vo.CinemasMovieVo;
import com.tyj.movie.vo.OrderPayVo;
import com.tyj.movie.vo.OrderVo;
import com.tyj.movie.vo.PayVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author tyj
 * @since 2021-06-28
 */
@RestController
@RequestMapping("/movie/order")
public class MovieTheatreOrderController {

    @Autowired
    MovieService movieService;

    @Autowired
    MovieTypeMapper movieTypeMapper;

    @Autowired
    MovieTheatreService movieTheatreService;

    @Autowired
    MovieTheatreShowService movieTheatreShowService;

    @Autowired
    RedisTemplate<String,String> redisTemplate;

    @Autowired
    MovieTheatreOrderService movieTheatreOrderService;

    @Autowired
    AlipayTemplate alipayTemplate;

    @Value("${order.expiration-time}")
    Integer expirationTime;


    /**
     * 去selectionSeat页面
     * @param movieId
     * @param movieShowId
     * @return
     */
    @RequestMapping("/selectionSeat")
    public ModelAndView selectionSeat(Long movieId,Long movieShowId){

        ModelAndView modelAndView=new ModelAndView();
        MovieTheatreShow movieTheatreShow = movieTheatreShowService.getMovieTheatreNameAndBrandById(movieShowId);
        //判断当前排片是否已经开始
        Date startDate = movieTheatreShow.getStartDate();
        Date nowDate=new Date();
        if (startDate.getTime()-nowDate.getTime()<0){
            //排片开始播放
            modelAndView.addObject("startState",0);
            modelAndView.setViewName("forward:/movie/theatre/cinemaDetail/"+movieTheatreShow.getMovieTheatreId());
            return modelAndView;
        }

        //封装日期显示日期

        Date date = movieTheatreShow.getStartDate();
        String dateFormat = DateUtil.getDateFormat(date);
        movieTheatreShow.setSessionTime(dateFormat);
        modelAndView.addObject("movieTheatreShow",movieTheatreShow);

        //查询redis购买座位
        List<String> buySeat =movieTheatreShowService.queryBuySeat(movieShowId);
        modelAndView.addObject("buySeat",buySeat);

        //查询电影信息
        List<String> movieTypes = movieTypeMapper.queryMovieTypesByMovieId(movieId);
        CinemasMovieVo movieVo=movieService.queryCinemasMovieVo(movieId);
        movieVo.setTypes(movieTypes);
        modelAndView.addObject("movieVo",movieVo);

        //随机一个防重令牌
        String uuid = UUID.randomUUID().toString();
        String token = uuid.replace("-", "");
        modelAndView.addObject("token",token);
        if (SecurityUtil.getSessionUser()!=null) {
            //将令牌存入redis
            redisTemplate.opsForValue().set(RedisConstant.USER_ORDER_TOKEN_PREFIX + SecurityUtil.getSessionUser().getId(), token, 300, TimeUnit.SECONDS);
            //将单价存入redis
            redisTemplate.opsForValue().set(RedisConstant.MOVIE_THEATRE_SHOW_PRICE + movieTheatreShow.getId(), movieTheatreShow.getPrice().toString(), 300, TimeUnit.SECONDS);
        }
        modelAndView.setViewName("selectionSeat");
        return modelAndView;
    }

    @RequestMapping("/submitOrder")
    public ModelAndView submitOrder(MovieTheatreOrderTo movieTheatreOrderTo){
        ModelAndView modelAndView=new ModelAndView();
        Integer state = movieTheatreOrderService.submitOrder(movieTheatreOrderTo);
        if (state==0){
            //成功
            modelAndView.setViewName("redirect:/orderSuccess?orderSn="+movieTheatreOrderTo.getOrderSn());
        }else if (state==1){
            //防重令牌失效
            modelAndView.setViewName("forward:selectionSeat?movieId="+movieTheatreOrderTo.getMovieId()+"&movieShowId="+movieTheatreOrderTo.getMovieTheatreShowId());
            modelAndView.addObject("msg","防重令牌失效");
        }else if (state==2){
            //防止恶意下单
            modelAndView.setViewName("forward:selectionSeat?movieId="+movieTheatreOrderTo.getMovieId()+"&movieShowId="+movieTheatreOrderTo.getMovieTheatreShowId());
            modelAndView.addObject("msg","订单未支付数量最大限制");
        }else if (state==3){
            //座位以被购买
            modelAndView.setViewName("forward:selectionSeat?movieId="+movieTheatreOrderTo.getMovieId()+"&movieShowId="+movieTheatreOrderTo.getMovieTheatreShowId());
            modelAndView.addObject("msg","座位以被购买");
        }else if (state==4){
            //金额不匹配
            modelAndView.setViewName("forward:selectionSeat?movieId="+movieTheatreOrderTo.getMovieId()+"&movieShowId="+movieTheatreOrderTo.getMovieTheatreShowId());
            modelAndView.addObject("msg","金额不匹配");
        }else {
            //服务器内部异常
            modelAndView.setViewName("forward:selectionSeat?movieId="+movieTheatreOrderTo.getMovieId()+"&movieShowId="+movieTheatreOrderTo.getMovieTheatreShowId());
            modelAndView.addObject("msg","服务器内部异常");
        }
        return modelAndView;
    }


    @RequestMapping("/pay")
    public ModelAndView orderPay(String orderSn) throws ParseException {
        ModelAndView modelAndView=new ModelAndView();
        OrderPayVo payVo=movieTheatreOrderService.queryOrderPayVo(orderSn);
        //判断是否超时
        if (payVo==null){
            modelAndView.addObject("msg","服务繁忙请稍后重试");
            modelAndView.setViewName("redirect:/orderSuccess?orderSn="+orderSn);
            return modelAndView;
        }
        //将日期转化为 今天 1月1日 12:10
        String startDate = payVo.getStartDate();
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date parse = simpleDateFormat.parse(startDate);
        String dateFormat = DateUtil.getDateFormat(parse);
        payVo.setStartDate(dateFormat);

        //计算毫秒 倒计时5分钟 300000
        long time = payVo.getCreateDate().getTime()+expirationTime*60*1000;
        long time1 = new Date().getTime();
        payVo.setFromTime(time-time1);

        modelAndView.addObject("payVo",payVo);
        modelAndView.setViewName("orderPay");
        return modelAndView;
    }

    @RequestMapping("/alipay/{orderSn}")
    public String alipay(@PathVariable("orderSn") String orderSn) throws AlipayApiException {
        PayVo payVo=movieTheatreOrderService.queryPayVoByOrderSn(orderSn);
        //返回一个页面
        String pay = alipayTemplate.pay(payVo);
        return pay;
    }

    /**
     * 查询订单
     * @return
     */
    @RequestMapping("/personalOrder")
    public ModelAndView personalOrder() throws ParseException {
        ModelAndView modelAndView=new ModelAndView();

        //查询订单
       List<OrderVo> orders = movieTheatreOrderService.queryUserOrder();
       modelAndView.addObject("orders",orders);

        modelAndView.setViewName("personal");
        return modelAndView;
    }

    /**
     *
     */
    @RequestMapping("/refund")
    public ModelAndView refund(String orderSn) throws AlipayApiException, ExecutionException, InterruptedException {
        ModelAndView modelAndView=new ModelAndView();
        Integer num = movieTheatreOrderService.refund(orderSn);
        if (num==1){
            modelAndView.addObject("msg","退款正在受理,请及时查看");
        }else if (num==2){
            modelAndView.addObject("msg","退款失败,只能在电影放映前30分钟退款");
        }else {
            modelAndView.addObject("msg","退款失败,服务器异常");
        }
        modelAndView.setViewName("redirect:/orderRefund");
        return modelAndView;
    }


}

